' Demonstrate operation of an LCD in 4-bit mode
'
' LCD should be connected as follows:
'       LCD     PICmicro
'       DB4     PortA.0
'       DB5     PortA.1
'       DB6     PortA.2
'       DB7     PortA.3
'       RS      PortA.4 (add 4.7K pullup resistor to 5 volts)
'       E       PortB.3
'       RW      Ground
'       Vdd     5 volts
'       Vss     Ground
'       Vo      20K potentiometer (or ground)
'       DB0-3   No connect

Symbol  PortA = 5       'PortA is register 5
Symbol  TrisA = $85     'PortA data direction is register hexadecimal 85
Symbol  Lcde = 3        'lcd enable line is Pin3

        Poke TrisA,0    'set all PortA lines to output
        Low Lcde        'start with lcd enable low

        Gosub lcdinit   'initialize the lcd

loop:   Gosub lcdclr    'clear lcd screen
        For B4 = 0 to 4 'send string to lcd one letter at a time
                Lookup B4,("Hello"),B2  'get letter from string
                Gosub lcddata   'send letter in B2 to lcd
        Next B4
        Pause 500       'wait .5 second

        Gosub lcdclr    'clear lcd screen
        For B4 = 0 to 4 'send string to lcd one letter at a time
                Lookup B4,("world"),B2  'get letter from string
                Gosub lcddata   'send letter in B2 to lcd
        Next B4
        Pause 500       'wait .5 second

        Goto loop       'do it forever


' subroutine to initialize the lcd - uses B2 and B3
lcdinit: Pause 15       'wait at least 15ms

        Poke PortA,3    'initialize the lcd
        Gosub lcdtog    'toggle the lcd enable line

        Pause 5         'wait at least 4.1ms

        Poke PortA,3    'initialize the lcd
        Gosub lcdtog    'toggle the lcd enable line

        Pause 1         'wait at least 100us

        Poke PortA,3    'initialize the lcd
        Gosub lcdtog    'toggle the lcd enable line

        Pause 1         'wait once more for good luck

        Poke PortA,2    'put lcd into 4 bit mode
        Gosub lcdtog    'toggle the lcd enable line

        B2 = $28        '4 bit mode, 2 lines, 5x7 font
        Gosub lcdcom    'send B2 to lcd

        B2 = $0c        'lcd display on, no cursor, no blink
        Gosub lcdcom    'send B2 to lcd

        B2 = $06        'lcd entry mode set, increment, no shift
        Goto lcdcom     'exit through send lcd command

' subroutine to clear the lcd screen - uses B2 and B3
lcdclr: B2 = 1          'set B2 to clear command and fall through to lcdcom

' subroutine to send a command to the lcd - uses B2 and B3
lcdcom: B3 = B2 / 16    'shift top 4 bits down to bottom 4 bits
        Poke PortA,B3   'send upper 4 bits to lcd
        Gosub lcdtog    'toggle the lcd enable line

        B3 = B2 & 15    'isolate bottom 4 bits
        Poke PortA,B3   'send lower 4 bits to lcd
        Gosub lcdtog    'toggle the lcd enable line

        Pause 1         'wait 1ms for write to complete
        Return

' subroutine to send data to the lcd - uses B2 and B3
lcddata: B3 = B2 / 16   'shift top 4 bits down to bottom 4 bits
        B3 = B3 + 16    'add in register select to indicate data
        Poke PortA,B3   'send upper 4 bits to lcd
        Gosub lcdtog    'toggle the lcd enable line

        B3 = B2 & 15    'isolate bottom 4 bits
        B3 = B3 + 16    'add in register select to indicate data
        Poke PortA,B3   'send lower 4 bits to lcd
        Gosub lcdtog    'toggle the lcd enable line

        Pause 1         'wait 1ms for write to complete
        Return

' subroutine to toggle the lcd enable line
lcdtog: High Lcde       'set lcd enable line high
        Low Lcde        'set lcd enable line low
        Return
